package org.example;

import java.util.*;
public class FilteredList <T> implements Iterable<T>{

    private List<T> L;
    private Predicate<T>  filter;

    public FilteredList(List<T> L, Predicate<T> filter) {
        this.L = L;
        this.filter = filter ;
    }


    @Override
    public Iterator<T> iterator() {
        return new FilteredListIterator();
    }

    private class FilteredListIterator implements Iterator<T> {

        private int index;
        public FilteredListIterator(){
            index= 0;
            moveIndex();

        }

        @Override
        public boolean hasNext() {
            return index<L.size();
        }

        @Override
        public T next() {
            if(!hasNext()){
                throw new NoSuchElementException();
            }

            //step 1 extrace the item to output
           T item = L.get(index);

            //step2 : prepare for the next time we call next
            moveIndex();
            //step3 return item we got before;

            return item;
        }

        /**
         * Move the index instance attribute to the next spot int the list
         * where an element that statisfies the predicate is
         */
        private void moveIndex() {

            while(index<L.size() &&  ! filter.test(L.get(index))) {
                index+=1;
            }
        }
    }
}
